package pres.wchen.oa.cor.shiro.shiro.validation;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.*;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.SerializeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

/**
 * @作者： wchen
 * @描述：
 * @创建时间： 2018/1/23 19:54
 * @版本：Copyright 2018, Inc. All Rights Reserved.
 * @修改信息： session校验器
 */
public class SessionValidationScheduler implements org.apache.shiro.session.mgt.SessionValidationScheduler, Runnable {


    private static final Logger log = LoggerFactory.getLogger(ExecutorServiceSessionValidationScheduler.class);
    ValidatingSessionManager sessionManager;
    private ScheduledExecutorService service;
    private long interval = DefaultWebSessionManager.DEFAULT_SESSION_VALIDATION_INTERVAL;
    private boolean enabled = false;

    public SessionValidationScheduler() {
        super();
    }

    public SessionValidationScheduler(ValidatingSessionManager sessionManager) {
        this.sessionManager = sessionManager;
    }

    public ValidatingSessionManager getSessionManager() {
        return this.sessionManager;
    }

    public void setSessionManager(ValidatingSessionManager sessionManager) {
        this.sessionManager = sessionManager;
    }

    public long getInterval() {
        return this.interval;
    }

    public void setInterval(long interval) {
        this.interval = interval;
    }

    public boolean isEnabled() {
        return this.enabled;
    }

    public void enableSessionValidation() {
        if (this.interval > 0L) {
            this.service = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
                public Thread newThread(Runnable r) {
                    Thread thread = new Thread(r);
                    thread.setDaemon(true);
                    return thread;
                }
            });
            this.service.scheduleAtFixedRate(this, this.interval, this.interval, TimeUnit.MILLISECONDS);
            this.enabled = true;
        }

    }

    public void run() {
        if (log.isDebugEnabled()) {
            log.debug("Executing session validation...");
        }
        System.out.println("-----------------会话校验开始----------------");
        long startTime = System.currentTimeMillis();
        this.sessionManager.validateSessions();

        //分页获取会话并验证
//        String sql = "select session from sessions limit ?,?";
//        int start = 0; //起始记录
//        int size = 20; //每页大小
////        List<String> sessionList = JdbcTemplate.queryForList(sql, String.class, start, size);
//        List<String> sessionList = new ArrayList<>();
//        while(sessionList.size() > 0) {
//            for(String sessionStr : sessionList) {
//                try {
//                    Session session = (Session) SerializeUtils.deserialize(sessionStr.getBytes());
//                    Method validateMethod = ReflectionUtils.findMethod(AbstractValidatingSessionManager.class, "validate", Session.class, SessionKey.class);
//                    validateMethod.setAccessible(true);
//                    ReflectionUtils.invokeMethod(validateMethod, sessionManager, session, new DefaultSessionKey(session.getId()));
//                } catch (Exception e) {
//                    log.error("session 校验处理失败。。。");
//                }
//            }
//            start = start + size;
////            sessionList = jdbcTemplate.queryForList(sql, String.class, start, size);
//
//        }


        long stopTime = System.currentTimeMillis();
        if (log.isDebugEnabled()) {
            log.debug("Session validation completed successfully in " + (stopTime - startTime) + " milliseconds.");
        }

    }

    public void disableSessionValidation() {
        this.service.shutdownNow();
        this.enabled = false;
    }
}
